package cn.itcast.n4.deadlock.v1;

import cn.itcast.n2.util.Sleeper;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j(topic = "c.TestDeadLock")
public class TestDeadLock {
    public static void main(String[] args) {
        final ArrayList<ChopStick> sticks = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            final ChopStick chopStick = new ChopStick(i+"");
            sticks.add(chopStick);
        }

//        //1.演示循环等待导致死锁问题
//        new Philosopher("大狗子",sticks.get(0),sticks.get(1)).start();
//        new Philosopher("二狗子",sticks.get(1),sticks.get(2)).start();
//        new Philosopher("三狗子",sticks.get(2),sticks.get(3)).start();
//        new Philosopher("四狗子",sticks.get(3),sticks.get(4)).start();
//        new Philosopher("小狗子",sticks.get(4),sticks.get(0)).start();

        //2.演示破坏循环等待，解决死锁问题-但会造成线程饥饿问题
        new Philosopher("大狗子",sticks.get(0),sticks.get(1)).start();
        new Philosopher("二狗子",sticks.get(1),sticks.get(2)).start();
        new Philosopher("三狗子",sticks.get(2),sticks.get(3)).start();
        new Philosopher("四狗子",sticks.get(3),sticks.get(4)).start();
        new Philosopher("小狗子",sticks.get(0),sticks.get(4)).start();

    }
}

@Slf4j(topic = "c.Philosopher")
class Philosopher extends Thread{
    ChopStick left;
    ChopStick right;

    public Philosopher(String name, ChopStick left, ChopStick right) {
        super(name);
        this.left = left;
        this.right = right;
    }

    @Override
    public void run() {
        while (true){
            synchronized (left){
                synchronized (right){
                    eat();
                }
            }
        }
    }

    private void eat(){
        log.debug("eating...");
        Sleeper.sleep(1);
    }
}

class ChopStick{
    String name;

    public ChopStick(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "ChopStick{" +
                "name='" + name + '\'' +
                '}';
    }
}
